#pragma once 
#include <iostream>
#include <cstdint>
#include <sys/socket.h>
#include <netinet/in.h>
#include "Commn.hpp"
#include "Log.hpp"
#include <string>
#include <arpa/inet.h>
using namespace LogModule;
const uint16_t gport = 8888;


class Udp_server
{
public:
    Udp_server()
        :_port(gport)
    {

    }
    void Init()
    {
        _socketfd = ::socket(AF_INET,SOCK_DGRAM,0); //获取文件描述符
        if (_socketfd < 0) 
        {
            Die(SOCKET_ERROR);
        }
        LOG(LogLevel::DEBUG) << "socket create success, fd is " << _socketfd;
        //进行绑定
        sockaddr_in local;
        local.sin_family = AF_INET; //本质也是无符号16位整数
        local.sin_port = ::htons(_port); //主机序列转为网络序列
        local.sin_addr.s_addr = INADDR_ANY; //32位无符号整型
        socklen_t len = sizeof(local);
        int n = ::bind(_socketfd,CONV(&local),len);
        if (n < 0)
        {
            Die(BIND_ERROR);
        }
        LOG(LogLevel::DEBUG) << "bind create success";
    }
    void Start()
    {
        char buffer[1024];
        sockaddr_in peer; //对端消息
        socklen_t len = sizeof(peer); //一定要初始化!!!!
        while(true)
        {
            int n = ::recvfrom(_socketfd,buffer,sizeof(buffer)-1,0,CONV(&peer),&len);
            if (n > 0)
            {
                buffer[n] = 0;
                std::string client = "echo server says# ";
                client += buffer;
                char Ip[64];
                ::inet_ntop(AF_INET,&(peer.sin_addr),Ip,64); //把网络ip地址转为点分十进制 192.132.168.10
                std::string ip = Ip;
                std::string port = std::to_string(ntohs(_port));
                LOG(LogLevel::INFO) << ip << ":" << port << "says# " << buffer;

                ::sendto(_socketfd,client.c_str(),client.size(),0,CONV(&peer),len);
            }
        }
    }
    ~Udp_server()
    {}
private:
    int _socketfd;
    uint16_t _port;
};

